package com.keba.lamp.complaint.service.impl;

import cn.hutool.core.convert.NumberChineseFormatter;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson.JSON;
import com.keba.basic.exception.BizException;
import com.keba.basic.utils.StrPool;
import com.keba.lamp.common.constant.AppendixType;
import com.keba.lamp.common.constant.BizConstant;
import com.keba.lamp.common.utils.MarkdownToPdf;
import com.keba.lamp.common.utils.WordUtil;
import com.keba.lamp.complaint.service.PdfCommonService;
import com.keba.lamp.complaint.vo.result.CaseFileResultVO;
import com.keba.lamp.complaint.vo.result.CaseResultVO;
import com.keba.lamp.complaint.vo.result.DefendantResultVO;
import com.keba.lamp.complaint.vo.result.EvidenceResultVO;
import com.keba.lamp.complaint.vo.result.PlaintffResultVO;
import com.keba.lamp.file.entity.File;
import com.keba.lamp.file.service.FileService;
import com.keba.lamp.file.strategy.FileContext;
import com.keba.lamp.file.vo.param.FileUploadVO;
import jakarta.annotation.Resource;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.mutable.MutableInt;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.concurrent.LinkedBlockingDeque;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
@Slf4j
@Service
public class PdfCommonServiceImpl implements PdfCommonService {
    @Resource
    private FileContext fileContext;
    @Autowired
    private FileService fileService;

    @Override
    public void createCasePdf(CaseResultVO caseResultVO, OutputStream outputStream, String fileType) throws Exception {
        MarkdownToPdf pdf = new MarkdownToPdf("SimSun.ttf", "simsunbd.ttf");
        List<String> palintffList = caseResultVO.getPlaintffResultVOList().stream().map(plaintffResultVO ->
                StringUtils.isBlank(plaintffResultVO.getSummarizeInfo()) ? "" : plaintffResultVO.getSummarizeInfo()
        ).collect(Collectors.toList());
        List<String> plaintffAgentList = caseResultVO.getPlaintffAgentResultVOList().stream().map(agentResultVO ->
                StringUtils.isBlank(agentResultVO.getSummarizeInfo()) ? "" : agentResultVO.getSummarizeInfo()
        ).collect(Collectors.toList());
        List<String> defendantList = caseResultVO.getDefendantResultVOList().stream().map(defendantResultVO ->
                StringUtils.isBlank(defendantResultVO.getSummarizeInfo()) ? "" : defendantResultVO.getSummarizeInfo()
        ).collect(Collectors.toList());
        List<String> defendantAgentList = caseResultVO.getDefendantAgentResultVOList().stream().map(agentResultVO ->
                StringUtils.isBlank(agentResultVO.getSummarizeInfo()) ? "" : agentResultVO.getSummarizeInfo()
        ).collect(Collectors.toList());
        LinkedHashMap complaintContent = JSON.parseObject(caseResultVO.getComplaintContent(), LinkedHashMap.class);
        if (BizConstant.FILE_SUFFIX_DOCX.equalsIgnoreCase(fileType)) {
            WordUtil.convert2Word(palintffList, plaintffAgentList, defendantList, defendantAgentList, complaintContent, outputStream);
        } else {
            pdf.createPdf(palintffList, plaintffAgentList, defendantList, defendantAgentList, complaintContent, outputStream);
        }
    }

    @Override
    public List<StreamResult> createPlaintffPdf(CaseResultVO caseResultVO) {
        List<PlaintffResultVO> plaintffResultVOList = caseResultVO.getPlaintffResultVOList();

        ThreadPoolExecutor executorService = buildThreadPool();
        List<Future<StreamResult>> futures = new ArrayList<>();
        MarkdownToPdf pdf = new MarkdownToPdf("SimSun.ttf", "simsunbd.ttf");
        for (int i = 0; i < plaintffResultVOList.size(); i++) {
            final int index = i + 1;
            final PlaintffResultVO plaintffResultVO = plaintffResultVOList.get(i);
            if (CollectionUtils.isEmpty(plaintffResultVO.getFileList())) {
                continue;
            }
            Future<StreamResult> submit = executorService.submit(() -> {
                List<MarkdownToPdf.FileInfo> fileInfoList = plaintffResultVO.getFileList().stream().map(caseFileResultVO -> {
                    MarkdownToPdf.FileInfo fileInfo = new MarkdownToPdf.FileInfo();
                    fileInfo.setFileType(caseFileResultVO.getFileType());
                    fileInfo.setUrl(caseFileResultVO.getUrl());
                    return fileInfo;
                }).collect(Collectors.toList());

                ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
                pdf.create(1, fileInfoList, byteArrayOutputStream);
                StreamResult streamResult = new StreamResult();
                streamResult.setIndex(index);
                streamResult.setName(plaintffResultVO.getName());
                streamResult.setByteArrayOutputStream(byteArrayOutputStream);
                return streamResult;
            });
            futures.add(submit);
        }
        executorService.shutdown();
        try {
            if (!executorService.awaitTermination(30, TimeUnit.SECONDS)) {
                executorService.shutdownNow();
            }
        } catch (InterruptedException e) {
            executorService.shutdownNow();
            Thread.currentThread().interrupt();
            throw new BizException("下载失败");
        }

        return futures.stream().map(future -> {
            try{
                return future.get();
            } catch (ExecutionException e) {
                log.error("下载失败:", e);
                throw new BizException("下载失败");
            } catch (InterruptedException e) {
                throw new BizException("下载失败");
            }
        }).collect(Collectors.toList());
    }


    @Override
    public List<StreamResult> createDefendantPdf(CaseResultVO caseResultVO) {
        List<DefendantResultVO> defendantResultVOList = caseResultVO.getDefendantResultVOList();

        ThreadPoolExecutor executorService = buildThreadPool();
        List<Future<StreamResult>> futures = new ArrayList<>();
        MarkdownToPdf pdf = new MarkdownToPdf("SimSun.ttf", "simsunbd.ttf");
        for (int i = 0; i < defendantResultVOList.size(); i++) {
            final int index = i + 1;
            final DefendantResultVO defendantResultVO = defendantResultVOList.get(i);
            if (CollectionUtils.isEmpty(defendantResultVO.getFileList())) {
                continue;
            }
            Future<StreamResult> submit = executorService.submit(() -> {
                List<MarkdownToPdf.FileInfo> fileInfoList = defendantResultVO.getFileList().stream().map(caseFileResultVO -> {
                    MarkdownToPdf.FileInfo fileInfo = new MarkdownToPdf.FileInfo();
                    fileInfo.setFileType(caseFileResultVO.getFileType());
                    fileInfo.setUrl(caseFileResultVO.getUrl());
                    return fileInfo;
                }).collect(Collectors.toList());
                ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
                pdf.create(1, fileInfoList, byteArrayOutputStream);
                StreamResult streamResult = new StreamResult();
                streamResult.setIndex(index);
                streamResult.setName(defendantResultVO.getName());
                streamResult.setByteArrayOutputStream(byteArrayOutputStream);
                return streamResult;
            });
            futures.add(submit);
        }
        executorService.shutdown();
        try {
            if (!executorService.awaitTermination(30, TimeUnit.SECONDS)) {
                executorService.shutdownNow();
            }
        } catch (InterruptedException e) {
            executorService.shutdownNow();
            Thread.currentThread().interrupt();
            throw new BizException("下载失败");
        }

        return futures.stream().map(future -> {
            try{
                return future.get();
            } catch (ExecutionException e) {
                log.error("下载失败:", e);
                throw new BizException("下载失败");
            } catch (InterruptedException e) {
                throw new BizException("下载失败");
            }
        }).collect(Collectors.toList());
    }

    @Override
    public void createEvidenceZip(CaseResultVO caseResultVO,  OutputStream outputStream) throws IOException {
        List<EvidenceResultVO> evidenceResultVOList = caseResultVO.getEvidenceResultVOList();
        MarkdownToPdf pdf = new MarkdownToPdf("SimSun.ttf", "simsunbd.ttf");
        ZipOutputStream zos = new ZipOutputStream(outputStream);

        ThreadPoolExecutor executorService = buildThreadPool();
        List<Future<EvidenceStreamResult>> futures = new ArrayList<>();
        MutableInt startPage = new MutableInt(1);
        for (int i = 0; i < evidenceResultVOList.size(); i++) {
            final int index = i;
            final int startPageValue = startPage.getValue();
            final EvidenceResultVO evidenceResultVO = evidenceResultVOList.get(i);
            Future<EvidenceStreamResult> submit = executorService.submit(() -> {
                List<MarkdownToPdf.FileInfo> fileInfoList = evidenceResultVO.getCaseFileResultVOList().stream().map(caseFileResultVO -> {
                    MarkdownToPdf.FileInfo fileInfo = new MarkdownToPdf.FileInfo();
                    fileInfo.setFileType(caseFileResultVO.getFileType());
                    fileInfo.setUrl(caseFileResultVO.getUrl());
                    return fileInfo;
                }).collect(Collectors.toList());
                ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
                pdf.create(startPageValue, fileInfoList, byteArrayOutputStream);
                EvidenceStreamResult evidenceStreamResult = new EvidenceStreamResult();
                evidenceStreamResult.setIndex(index);
                evidenceStreamResult.setComponentName(evidenceResultVO.getComponentName());
                evidenceStreamResult.setByteArrayOutputStream(byteArrayOutputStream);
                return evidenceStreamResult;
            });
            futures.add(submit);
            int totalPicNum = evidenceResultVO.getCaseFileResultVOList().stream().mapToInt(CaseFileResultVO::getPicNum).sum();
            startPage.add(totalPicNum);
        }
        executorService.shutdown();
        try {
            if (!executorService.awaitTermination(60, TimeUnit.SECONDS)) {
                executorService.shutdownNow();
            }
        } catch (InterruptedException e) {
            executorService.shutdownNow();
            Thread.currentThread().interrupt();
            throw new BizException("下载失败");
        }
        for (Future<EvidenceStreamResult> future : futures) {
            try {
                EvidenceStreamResult evidenceStreamResult = future.get();
                Integer i = evidenceStreamResult.getIndex();
                String componentName = evidenceStreamResult.getComponentName();
                ByteArrayOutputStream byteArrayOutputStream = evidenceStreamResult.getByteArrayOutputStream();
                String pdfIndexName = NumberChineseFormatter.format(i + 1, false);
                ZipEntry zipEntry = new ZipEntry("证据第" + pdfIndexName + "组 " + componentName + ".pdf");
                zos.putNextEntry(zipEntry);
                zos.write(byteArrayOutputStream.toByteArray());
                zos.closeEntry();
            } catch (ExecutionException e) {
                log.error("下载失败:", e);
                throw new BizException("下载失败");
            } catch (InterruptedException e) {
                throw new BizException("下载失败");
            }
        }

        zos.close();
    }


    @Override
    public ByteArrayOutputStream createFileZip(List<CaseFileResultVO> fileList) throws IOException {
        if (CollectionUtils.isNotEmpty(fileList)) {
            ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
            ZipOutputStream zos = new ZipOutputStream(outputStream);
            ThreadPoolExecutor executorService = buildThreadPool();
            List<Future<FileStreamResult>> futures = new ArrayList<>();
            for (int i = 0; i < fileList.size(); i++) {
                CaseFileResultVO caseFileResultVO = fileList.get(i);
                Future<FileStreamResult> submit = executorService.submit(() -> {
                    ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
                    HttpUtil.download(caseFileResultVO.getUrl(), byteArrayOutputStream, true);
                    FileStreamResult fileStreamResult = new FileStreamResult();
                    fileStreamResult.setId(caseFileResultVO.getId());
                    fileStreamResult.setByteArrayOutputStream(byteArrayOutputStream);
                    return fileStreamResult;
                });
                futures.add(submit);
            }
            executorService.shutdown();
            try {
                if (!executorService.awaitTermination(60, TimeUnit.SECONDS)) {
                    executorService.shutdownNow();
                }
            } catch (InterruptedException e) {
                executorService.shutdownNow();
                Thread.currentThread().interrupt();
                throw new BizException("下载失败");
            }
            Map<String, Integer> originalFileNameIndex = new HashMap<>();
            for (Future<FileStreamResult> future : futures) {
                try {
                    FileStreamResult fileStreamResult = future.get();
                    String originalFileName = fileList.stream().filter(file ->
                            Objects.equals(fileStreamResult.getId(), file.getId())
                    ).findFirst().get().getOriginalFileName();
                    //解决文件名重名下载失败问题
                    if (originalFileNameIndex.containsKey(originalFileName)) {
                        Integer nameIndex = originalFileNameIndex.get(originalFileName) + 1;
                        originalFileNameIndex.put(originalFileName, nameIndex);
//                        int splitIndex = originalFileName.lastIndexOf(".");
//                        originalFileName = originalFileName.substring(0, splitIndex) + nameIndex + originalFileName.substring(splitIndex);
                        originalFileName = StrUtil.strBuilder(originalFileName).insert(originalFileName.lastIndexOf(StrPool.DOT), "(" + nameIndex + ")").toString();
                    } else {
                        originalFileNameIndex.put(originalFileName, 0);
                    }
                    ByteArrayOutputStream byteArrayOutputStream = fileStreamResult.getByteArrayOutputStream();
                    ZipEntry zipEntry = new ZipEntry(originalFileName);
                    zos.putNextEntry(zipEntry);
                    zos.write(byteArrayOutputStream.toByteArray());
                    zos.closeEntry();
                } catch (ExecutionException e) {
                    log.error("下载失败:", e);
                    throw new BizException("下载失败");
                } catch (InterruptedException e) {
                    throw new BizException("下载失败");
                }
            }
            zos.close();
            return outputStream;
        }
        return null;
    }


    @Override
    public ByteArrayOutputStream createFileZipByFileIdList(List<Long> fileIdList) throws IOException {
        if (CollectionUtils.isNotEmpty(fileIdList)) {
            ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
            ZipOutputStream zos = new ZipOutputStream(outputStream);
            ThreadPoolExecutor executorService = buildThreadPool();
            List<Future<FileStreamResult>> futures = new ArrayList<>();
            for (int i = 0; i < fileIdList.size(); i++) {
                Long fileId = fileIdList.get(i);
                File file = fileService.getById(fileId);
                Future<FileStreamResult> submit = executorService.submit(() -> {
                    ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
                    HttpUtil.download(file.getUrl(), byteArrayOutputStream, true);
                    FileStreamResult fileStreamResult = new FileStreamResult();
                    fileStreamResult.setId(fileId);
                    fileStreamResult.setName(file.getOriginalFileName());
                    fileStreamResult.setByteArrayOutputStream(byteArrayOutputStream);
                    return fileStreamResult;
                });
                futures.add(submit);
            }
            executorService.shutdown();
            try {
                if (!executorService.awaitTermination(60, TimeUnit.SECONDS)) {
                    executorService.shutdownNow();
                }
            } catch (InterruptedException e) {
                executorService.shutdownNow();
                Thread.currentThread().interrupt();
                throw new BizException("下载失败");
            }
            Map<String, Integer> originalFileNameIndex = new HashMap<>();
            for (Future<FileStreamResult> future : futures) {
                try {
                    FileStreamResult fileStreamResult = future.get();
                    String originalFileName = fileStreamResult.getName();
                    //解决文件名重名下载失败问题
                    if (originalFileNameIndex.containsKey(originalFileName)) {
                        Integer nameIndex = originalFileNameIndex.get(originalFileName) + 1;
                        originalFileNameIndex.put(originalFileName, nameIndex);
                        originalFileName = StrUtil.strBuilder(originalFileName).insert(originalFileName.lastIndexOf(StrPool.DOT), "(" + nameIndex + ")").toString();
                        //int splitIndex = originalFileName.lastIndexOf(".");
                        //originalFileName = originalFileName.substring(0, splitIndex) + nameIndex + originalFileName.substring(splitIndex);
                    } else {
                        originalFileNameIndex.put(originalFileName, 0);
                    }
                    ByteArrayOutputStream byteArrayOutputStream = fileStreamResult.getByteArrayOutputStream();
                    ZipEntry zipEntry = new ZipEntry(originalFileName);
                    zos.putNextEntry(zipEntry);
                    zos.write(byteArrayOutputStream.toByteArray());
                    zos.closeEntry();
                } catch (ExecutionException e) {
                    log.error("下载失败:", e);
                    throw new BizException("下载失败");
                } catch (InterruptedException e) {
                    throw new BizException("下载失败");
                }
            }
            zos.close();
            return outputStream;
        }
        return null;
    }

    @Override
    public void createEvidencePdf(CaseResultVO caseResultVO, OutputStream outputStream, String fileType) throws Exception {
        List<String> palintffList = caseResultVO.getPlaintffResultVOList().stream().map(plaintffResultVO ->
                StringUtils.isBlank(plaintffResultVO.getName()) ? "" : plaintffResultVO.getName()
        ).collect(Collectors.toList());
        List<String> defendantList = caseResultVO.getDefendantResultVOList().stream().map(defendantResultVO ->
                StringUtils.isBlank(defendantResultVO.getName()) ? "" : defendantResultVO.getName()
        ).collect(Collectors.toList());
        if (BizConstant.FILE_SUFFIX_DOCX.equalsIgnoreCase(fileType)) {
            WordUtil.create(palintffList, defendantList, getTableHtml(caseResultVO), outputStream);
        } else {
            MarkdownToPdf pdf = new MarkdownToPdf("SimSun.ttf", "simsunbd.ttf");
            pdf.create(palintffList, defendantList, getTableHtml(caseResultVO), outputStream);
        }
    }

    @Override
    public void createCaseZip(CaseResultVO caseResultVO, OutputStream outputStream) throws Exception {
        ZipOutputStream zos = new ZipOutputStream(outputStream);
        //起诉书PDF版
        ByteArrayOutputStream casePdfOutputStream = new ByteArrayOutputStream();
        //起诉书word版
        ByteArrayOutputStream caseWordOutputStream = new ByteArrayOutputStream();
        //证据目录PDF版
        ByteArrayOutputStream evidencePdfOutputStream = new ByteArrayOutputStream();
        //证据目录word版
        ByteArrayOutputStream evidenceWordOutputStream = new ByteArrayOutputStream();
        if (BizConstant.CASE_STATE_SUCCESS_10.equals(caseResultVO.getCaseState())) {
            this.createCasePdf(caseResultVO, casePdfOutputStream, BizConstant.FILE_SUFFIX_PDF);
            this.createCasePdf(caseResultVO, caseWordOutputStream, BizConstant.FILE_SUFFIX_DOCX);
            this.createEvidencePdf(caseResultVO, evidencePdfOutputStream, BizConstant.FILE_SUFFIX_PDF);
            this.createEvidencePdf(caseResultVO, evidenceWordOutputStream, BizConstant.FILE_SUFFIX_DOCX);
        }
        //证据压缩包
        ByteArrayOutputStream evidenceZipOutputStream = new ByteArrayOutputStream();
        if (CollectionUtils.isNotEmpty(caseResultVO.getEvidenceResultVOList())) {
            this.createEvidenceZip(caseResultVO, evidenceZipOutputStream);
        }
        //原告、被告PDF版
        List<PdfCommonServiceImpl.StreamResult> plaintffPdfList = new ArrayList<>();
        if (CollectionUtils.isNotEmpty(caseResultVO.getPlaintffResultVOList())) {
            plaintffPdfList = this.createPlaintffPdf(caseResultVO);
        }
        List<PdfCommonServiceImpl.StreamResult> defendantPdfList = new ArrayList<>();
        if (CollectionUtils.isNotEmpty(caseResultVO.getDefendantResultVOList())) {
            defendantPdfList = this.createDefendantPdf(caseResultVO);
        }

        //起诉状文件（签字版）
        ByteArrayOutputStream suitFileOutputStream = this.createFileZip(caseResultVO.getSuitFileList());
        //证据目录（签字版）
        ByteArrayOutputStream evidenceSignFileOutputStream = this.createFileZip(caseResultVO.getEvidenceSignFileList());
        //委托代理人手续和身份证明
        List<CaseFileResultVO> plaintffAgentFileList = new ArrayList<>();
        if (CollectionUtils.isNotEmpty(caseResultVO.getPlaintffAgentResultVOList())) {
            caseResultVO.getPlaintffAgentResultVOList().stream().filter(agentResultVO ->
                    CollectionUtils.isNotEmpty(agentResultVO.getFileList())
            ).forEach(agentResultVO -> {
                plaintffAgentFileList.addAll(agentResultVO.getFileList());
            });
        }
        ByteArrayOutputStream identityMaterialFileOutputStream = this.createFileZip(plaintffAgentFileList);
        //送达地址确认书
        ByteArrayOutputStream deliveryAddressFileOutputStream = this.createFileZip(caseResultVO.getDeliveryAddressFileList());
        //银行结算确认书
        ByteArrayOutputStream settleConfirmFileOutputStream = this.createFileZip(caseResultVO.getSettleConfirmFileList());
        //其他材料
        ByteArrayOutputStream otherFileOutputStream = this.createFileZip(caseResultVO.getOtherFileList());

        for (PdfCommonServiceImpl.StreamResult streamResult : plaintffPdfList) {
            ZipEntry casePdfEntry = new ZipEntry(caseResultVO.getCaseName() + "原告" + streamResult.getIndex() + "身份信息.pdf");
            zos.putNextEntry(casePdfEntry);
            zos.write(streamResult.getByteArrayOutputStream().toByteArray());
            zos.closeEntry();
        }

        for (PdfCommonServiceImpl.StreamResult streamResult : defendantPdfList) {
            ZipEntry casePdfEntry = new ZipEntry(caseResultVO.getCaseName() + "被告" + streamResult.getIndex() + "身份信息.pdf");
            zos.putNextEntry(casePdfEntry);
            zos.write(streamResult.getByteArrayOutputStream().toByteArray());
            zos.closeEntry();
        }

        if (ArrayUtil.isNotEmpty(casePdfOutputStream.toByteArray())) {
            ZipEntry casePdfEntry = new ZipEntry(caseResultVO.getCaseName() + "起诉书.pdf");
            zos.putNextEntry(casePdfEntry);
            zos.write(casePdfOutputStream.toByteArray());
            zos.closeEntry();
        }

        if (ArrayUtil.isNotEmpty(caseWordOutputStream.toByteArray())) {
            ZipEntry caseWordEntry = new ZipEntry(caseResultVO.getCaseName() + "起诉书.docx");
            zos.putNextEntry(caseWordEntry);
            zos.write(caseWordOutputStream.toByteArray());
            zos.closeEntry();
        }

        if (ArrayUtil.isNotEmpty(evidencePdfOutputStream.toByteArray())) {
            ZipEntry evidencePdfEntry = new ZipEntry(caseResultVO.getCaseName() + "证据目录.pdf");
            zos.putNextEntry(evidencePdfEntry);
            zos.write(evidencePdfOutputStream.toByteArray());
            zos.closeEntry();

        }

        if (ArrayUtil.isNotEmpty(evidenceWordOutputStream.toByteArray())) {
            ZipEntry evidenceWordEntry = new ZipEntry(caseResultVO.getCaseName() + "证据目录.docx");
            zos.putNextEntry(evidenceWordEntry);
            zos.write(evidenceWordOutputStream.toByteArray());
            zos.closeEntry();
        }

        if (ArrayUtil.isNotEmpty(evidenceZipOutputStream.toByteArray())) {
            ZipEntry evidenceZipEntry = new ZipEntry(caseResultVO.getCaseName() + "证据.zip");
            zos.putNextEntry(evidenceZipEntry);
            zos.write(evidenceZipOutputStream.toByteArray());
            zos.closeEntry();
        }

        if (Objects.nonNull(suitFileOutputStream)) {
            ZipEntry suitFileZipEntry = new ZipEntry(caseResultVO.getCaseName() + "起诉状文件（签字版）.zip");
            zos.putNextEntry(suitFileZipEntry);
            zos.write(suitFileOutputStream.toByteArray());
            zos.closeEntry();
        }

        if (Objects.nonNull(evidenceSignFileOutputStream)) {
            ZipEntry evidenceSignFileZipEntry = new ZipEntry(caseResultVO.getCaseName() + "证据目录（签字版）.zip");
            zos.putNextEntry(evidenceSignFileZipEntry);
            zos.write(evidenceSignFileOutputStream.toByteArray());
            zos.closeEntry();
        }

        if (Objects.nonNull(identityMaterialFileOutputStream)) {
            ZipEntry identityMaterialFileZipEntry = new ZipEntry(caseResultVO.getCaseName() + "委托代理人手续和身份证明.zip");
            zos.putNextEntry(identityMaterialFileZipEntry);
            zos.write(identityMaterialFileOutputStream.toByteArray());
            zos.closeEntry();
        }
        if (Objects.nonNull(deliveryAddressFileOutputStream)) {
            ZipEntry deliveryAddressFileZipEntry = new ZipEntry(caseResultVO.getCaseName() + "送达地址确认书.zip");
            zos.putNextEntry(deliveryAddressFileZipEntry);
            zos.write(deliveryAddressFileOutputStream.toByteArray());
            zos.closeEntry();
        }
        if (Objects.nonNull(settleConfirmFileOutputStream)) {
            ZipEntry settleConfirmFileZipEntry = new ZipEntry(caseResultVO.getCaseName() + "银行结算确认书.zip");
            zos.putNextEntry(settleConfirmFileZipEntry);
            zos.write(settleConfirmFileOutputStream.toByteArray());
            zos.closeEntry();
        }
        if (Objects.nonNull(otherFileOutputStream)) {
            ZipEntry otherFileZipEntry = new ZipEntry(caseResultVO.getCaseName() + "其他材料.zip");
            zos.putNextEntry(otherFileZipEntry);
            zos.write(otherFileOutputStream.toByteArray());
            zos.closeEntry();
        }
        zos.close();
    }

    @Override
    public String uploadCaseZip(CaseResultVO caseResultVO) throws Exception {
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        this.createCaseZip(caseResultVO, outputStream);
        outputStream.close();
        FileUploadVO fileUploadVO = new FileUploadVO();
        fileUploadVO.setBizType(AppendixType.Complaint.COMPLAINT__CASE__ZIP__FILE);
        String caseName = StringUtils.isBlank(caseResultVO.getCaseName()) ? "" : caseResultVO.getCaseName();
        String fileName = caseName + "立案材料.zip";
        File fileFile = fileContext.upload(new ByteArrayInputStream(outputStream.toByteArray()), fileName, fileUploadVO);
        return fileFile.getUrl();
    }

    private String getTableHtml(CaseResultVO caseResultVO) {
        StringBuffer sb = new StringBuffer();
//        List<PlaintffResultVO> plaintffResultVOList = caseResultVO.getPlaintffResultVOList();
//        for (int i = 0; i < plaintffResultVOList.size(); i++) {
//            String title = plaintffResultVOList.size() > 1 ? "原告" + (i + 1) : "原告";
//            PlaintffResultVO plaintffResultVO = plaintffResultVOList.get(i);
//            String content = title + ":" + plaintffResultVO.getName();
//            String row = String.format("<h3>%s</h3> ", content);
//            sb.append(row).append("\n");
//        }
//
//        List<DefendantResultVO> defendantResultVOList = caseResultVO.getDefendantResultVOList();
//        for (int i = 0; i < defendantResultVOList.size(); i++) {
//            String title = defendantResultVOList.size() > 1 ? "被告" + (i + 1) : "被告";
//            DefendantResultVO defendantResultVO = defendantResultVOList.get(i);
//            String content = title + ":" + defendantResultVO.getName();
//            String row = String.format("<h3>%s</h3> ", content);
//            sb.append(row).append("\n");
//        }
        //总宽度 21cm * 567 = 11907缇
        //左边距：1587
        //右边距：1474
        //剩余空间：11907-1587-1474 = 8846
        //表格宽度：442
        List<EvidenceResultVO> evidenceResultVOList = caseResultVO.getEvidenceResultVOList();
        sb
                .append("<table class=\"ui celled table\"> \n")
                .append(" <thead> \n" +
                        "  <tr> \n" +
                        "   <th width=\"53\">证据</th> \n" +
                        "   <th width=\"106\">证据名称</th> \n" +
                        "   <th>证明内容</th> \n" +
                        "   <th width=\"53\">证明来源</th> \n" +
                        "   <th width=\"53\">页数</th> \n" +
                        "  </tr> \n" +
                        " </thead> \n")
                .append(" <tbody> ")
        ;
        for (int i = 0; i < evidenceResultVOList.size(); i++) {
            EvidenceResultVO evidenceGroup = evidenceResultVOList.get(i);
            Integer startPage = evidenceGroup.getStartPage();
            Integer endPage = evidenceGroup.getEndPage();
            String pageStr = "";
            if (Objects.nonNull(startPage) && Objects.nonNull(endPage)) {
                pageStr = startPage != endPage ?  (startPage + "-" + endPage + "页") : (startPage + "页");
            }
            String row = String.format("<tr> \n" +
                            "   <td>%s</td> \n" +
                            "   <td>%s</td> \n" +
                            "   <td>%s</td> \n" +
                            "   <td>%s</td> \n" +
                            "   <td>%s</td> \n" +
                            "  </tr> \n",
                    "第" + (i + 1) + "组",
                    evidenceGroup.getComponentName(),
                    StringUtils.isBlank(evidenceGroup.getSummarizeInfo()) ? "" : evidenceGroup.getSummarizeInfo(),
                    "原告提供",
                    pageStr);
            sb.append(row);
        }
        sb.append(" </tbody> ");
        sb.append("</table>");
        return sb.toString();
    }


    @Data
    public static class EvidenceStreamResult {
        private Integer index;
        private String componentName;
        private ByteArrayOutputStream byteArrayOutputStream;
    }

    @Data
    public static class FileStreamResult {
        private Long id;
        private String name;
        private ByteArrayOutputStream byteArrayOutputStream;
    }


    @Data
    public static class StreamResult {
        private Integer index;
        private String name;
        private ByteArrayOutputStream byteArrayOutputStream;
    }

    /**
     * 定义一个线程池
     *
     * @return
     */
    private ThreadPoolExecutor buildThreadPool() {
        ThreadPoolExecutor executor = new ThreadPoolExecutor(
                8,
                40,
                10, TimeUnit.SECONDS,
                new LinkedBlockingDeque<>(200)); //有界队列，容量200;
        return executor;
    }
}
